package com.forest.datachangetracker.utils;

import cn.hutool.extra.spring.SpringUtil;
import com.forest.datachangetracker.config.DataChangeTrackerProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 *
 * 实体ID提取工具类
 *
 * @author forest
 */
public class EntityIdExtractor {

    private static final Logger log = LoggerFactory.getLogger(EntityIdExtractor.class);

    /**
     * 尝试从实体对象中提取ID
     *
     * @param entity 实体对象
     * @return ID字符串，如果无法提取则返回null
     */
    public static String extractId(Object entity) {
        if (entity == null) {
            return null;
        }

        // 尝试通过getId方法获取
        try {
            Method getIdMethod = entity.getClass().getMethod("getId");
            Object idValue = getIdMethod.invoke(entity);
            if (idValue != null) {
                return idValue.toString();
            }
        } catch (Exception e) {
            // 继续尝试其他方式
        }

        // 尝试通过字段获取
        try {
            Field idField = entity.getClass().getDeclaredField("id");
            idField.setAccessible(true);
            Object idValue = idField.get(entity);
            if (idValue != null) {
                return idValue.toString();
            }
        } catch (Exception e) {
            log.debug("无法通过反射获取实体ID: {}", entity.getClass().getSimpleName());
        }

        //获取id字段列表
        DataChangeTrackerProperties properties = SpringUtil.getBean(DataChangeTrackerProperties.class);
        // 尝试其他常见ID字段名
        String[] commonIdFields = properties.getKeyField().split(",");
        for (String fieldName : commonIdFields) {
            try {
                Field field = entity.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                Object idValue = field.get(entity);
                if (idValue != null) {
                    return idValue.toString();
                }
            } catch (Exception e) {
                // 忽略，继续尝试下一个字段
            }
        }

        return null;
    }
}
